from datetime import datetime
from typing import Optional, List
from pydantic import BaseModel, Field, EmailStr, validator
from bson import ObjectId
from enum import Enum
import re
from .base import PyObjectId

class UserStatus(str, Enum):
    ACTIVE = "active"      # 激活
    INACTIVE = "inactive"  # 禁用
    DELETED = "deleted"    # 已删除

class UserRole(str, Enum):
    ADMIN = "admin"
    PROJECT_MANAGER = "project_manager"
    PRODUCT_MANAGER = "product_manager"
    OPERATIONS_SPECIALIST = "operations_specialist"
    OPS_ENGINEER = "ops_engineer"
    DEVELOPER = "developer"
    TESTER = "tester"
    VIEWER = "viewer"
    USER = "user"
    OWNER = "owner"

class UserBase(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, description="用户名，必须唯一")
    name: str = Field(..., min_length=1, max_length=100)
    email: EmailStr
    department_id: Optional[str] = Field(None, description="部门ID")
    position: Optional[str] = None
    phone: Optional[str] = None
    avatar: Optional[str] = None
    bio: Optional[str] = None
    
    @validator('username')
    def validate_username(cls, v):
        if not re.match(r'^[a-zA-Z0-9_]+$', v):
            raise ValueError('用户名只能包含字母、数字和下划线')
        return v

class UserCreate(UserBase):
    password: str = Field(..., min_length=6)
    status: UserStatus = Field(default=UserStatus.ACTIVE, description="用户状态")
    system_roles: List[str] = Field(default=[], description="系统角色ID列表")
    roles: List[str] = Field(default=[], description="系统角色代码列表（优先使用）")
    is_verified: Optional[bool] = Field(default=False, description="是否已验证邮箱")

class UserUpdate(BaseModel):
    username: Optional[str] = Field(None, min_length=3, max_length=50, description="用户名，必须唯一")
    name: Optional[str] = None
    email: Optional[EmailStr] = None
    department: Optional[str] = None
    position: Optional[str] = None
    phone: Optional[str] = None
    avatar: Optional[str] = None
    bio: Optional[str] = None
    status: Optional[UserStatus] = None
    system_roles: Optional[List[str]] = None
    roles: Optional[List[str]] = None
    
    @validator('username')
    def validate_username(cls, v):
        if v is not None and not re.match(r'^[a-zA-Z0-9_]+$', v):
            raise ValueError('用户名只能包含字母、数字和下划线')
        return v

class UserInDB(UserBase):
    id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
    created_at: datetime
    updated_at: datetime
    status: UserStatus = UserStatus.ACTIVE
    is_verified: bool = False
    system_roles: List[str] = []

    class Config:
        populate_by_name = True
        arbitrary_types_allowed = True
        json_encoders = {ObjectId: str}

class User(UserBase):
    id: str
    status: UserStatus
    is_verified: bool
    system_roles: List[str]
    permissions: List[str]
    created_at: datetime
    updated_at: datetime
    last_login: Optional[datetime] = None
    login_count: int = 0

class UserLogin(BaseModel):
    username: str  # 可以是用户名或邮箱
    password: str
    remember: bool = False

class UserResponse(BaseModel):
    id: str
    username: str
    name: str
    email: str
    department_id: Optional[str] = None
    department: Optional[str] = Field(None, description="部门名称")
    position: Optional[str] = None
    phone: Optional[str] = None
    avatar: Optional[str] = None
    status: UserStatus
    is_verified: bool
    system_roles: List[str]
    roles: List[str] = []
    permissions: List[str]
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    last_login: Optional[datetime] = None
    login_count: int = 0

class ChangePassword(BaseModel):
    old_password: str
    new_password: str = Field(..., min_length=6)
    confirm_password: str

class ResetPassword(BaseModel):
    token: str
    password: str = Field(..., min_length=6)
    confirm_password: str

class ForgotPassword(BaseModel):
    email: EmailStr

class TokenData(BaseModel):
    user_id: str
    email: str
    system_roles: List[str]
    permissions: List[str]

class Token(BaseModel):
    access_token: str
    token_type: str = "bearer"
    expires_in: int
    user: UserResponse


class RefreshTokenRequest(BaseModel):
    refresh_token: str